﻿using CKS.Core.Framework;
using CKS.PLC.Core;
using FreeSql;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Model.Enums;
using ZR.Model.Models.ProductionControl;

namespace CKS.PLC.Action.Subscription {

    /// <summary>
    /// 子码绑定订阅点
    /// </summary>
    [SubscribeAction(SubcodeBindingName.SubscribeBindingActionKey)]
    public class SubcodeBindingAction : SubscribeBase {
        public SubcodeBindingAction(DecodeValue decodeValue) : base(decodeValue) {

        }

        public override void ExecuteAction(Dictionary<string, object> execParams) {

            using (var ObjectCo = base.FreeSql.Ado.MasterPool.Get()) {
                var result = DecodeValue.Value.ToInt();
                var position = DecodeValue.Position;
                var conn = ObjectCo.Value;
                //回复绑定关系点位
                var replyRelBindingPos = DecodeValue.GetReplyPosition(position, actionIdFieldFilter: true, actionKeyFieldFilter: true);

                if (result == 1) {//条码绑定

                    //获取绑定位的条码字段位置
                    var mainCodeBindingPosition = DecodeValue.GetPositionByActionKey(position, SubcodeBindingName.PrimaryCodeBindingActionKey);
                    if (mainCodeBindingPosition == null) {
                        WriteLogUI($"主产品码，未配置绑定的主产品码ActionKey字段");
                        WriteInt16(replyRelBindingPos, -1);
                        return;
                    }

                    //获取绑定位的条码值
                    var mainCodeBindingValue = DecodeValue.GetLinkDecodeObject(mainCodeBindingPosition).CharString.TrimEnd();
                    //如果条码值为空，则不进行处理
                    if (string.IsNullOrEmpty(mainCodeBindingValue)) {
                        WriteLogUI("绑定的主产品码值为空");
                        WriteInt16(replyRelBindingPos, 99);
                        return;
                    }

                    if (position.ActionId == 1) {//托盘码绑定

                        //获取托盘码字段位置
                        var palletCodePosition = DecodeValue.GetPositionByActionKey(position, SubcodeBindingName.PalletCodeBindingActionKey);
                        if (palletCodePosition == null) {
                            WriteLogUI($"托盘码，未配置绑定的托盘码ActionKey字段");
                            WriteInt16(replyRelBindingPos, -1);
                            return;
                        }

                        //获取托盘码值
                        var palletCodeValue = DecodeValue.GetLinkDecodeObject(palletCodePosition).CharString.TrimEnd();
                        //如果托盘码值为空，则不进行处理
                        if (string.IsNullOrEmpty(palletCodeValue)) {
                            WriteLogUI("绑定的托盘码值为空");
                            WriteInt16(replyRelBindingPos, 99);
                            return;
                        }

                        var barRelRec = conn.Select<CksBarcodeRelationshipRecord>().Where(o => o.Type == ZR.Model.Enums.eBarCodeRelType.PalletCode && o.PrimaryCode == mainCodeBindingValue).ToList();
                        if (barRelRec != null && barRelRec.Any(o => !o.IsDeleted)) {
                            var rec = barRelRec.Where(o => !o.IsDeleted).FirstOrDefault();
                            WriteLogUI($"当前主产品码已存在托盘绑定关系，绑定记录ID：{rec.Id}，产品码：{mainCodeBindingValue}，已绑定托盘：{rec.SubcodeCode}");
                            WriteInt16(replyRelBindingPos, 11);
                            return;
                        }
                        barRelRec = conn.Select<CksBarcodeRelationshipRecord>().Where(o => o.Type == ZR.Model.Enums.eBarCodeRelType.PalletCode && o.SubcodeCode == palletCodeValue).ToList();
                        if (barRelRec != null && barRelRec.Any(o => !o.IsDeleted)) {
                            var rec = barRelRec.Where(o => !o.IsDeleted).FirstOrDefault();
                            WriteLogUI($"当前托盘码已存在托盘绑定关系，绑定记录ID：{rec.Id}，托盘码：{palletCodeValue}，已绑定产品：{rec.PrimaryCode}");
                            WriteInt16(replyRelBindingPos, 11);
                            return;
                        }

                        CksBarcodeRelationshipRecord cksBarcodeRelationshipRecord = new CksBarcodeRelationshipRecord {
                            PrimaryCode = mainCodeBindingValue,
                            SubcodeCode = palletCodeValue,
                            PlcID = position.PlcId,
                            Type = eBarCodeRelType.PalletCode,
                            CreatedTime = DateTime.Now,
                            ReadDB = position.BlockDb, //设置读取DB块
                        };

                        //插入新条码关系记录
                        var diff = conn.Insert(cksBarcodeRelationshipRecord).ExecuteAffrows();
                        if (diff <= 0) {
                            WriteInt16(replyRelBindingPos, 2);
                        }
                        WriteInt16(replyRelBindingPos, 1);

                        WriteLogUI($"条码、托盘码关系绑定记录，主产品码：{mainCodeBindingValue}，托盘子码：{palletCodeValue}，保存托盘绑定关系成功");

                    } else if (position.ActionId == 2) {//子码绑定

                        //获取子码字段位置
                        var subCodePosition = DecodeValue.GetPositionByActionKey(position, SubcodeBindingName.SubCodeBindingActionKey);
                        if (subCodePosition == null) {
                            WriteLogUI($"子码，未配置绑定的子码ActionKey字段");
                            WriteInt16(replyRelBindingPos, -1);
                            return;
                        }

                        //获取子码值
                        var subCodeValue = DecodeValue.GetLinkDecodeObject(subCodePosition).CharString.TrimEnd();
                        //如果子码值为空，则不进行处理
                        if (string.IsNullOrEmpty(subCodeValue)) {
                            WriteLogUI("子码绑定值为空");
                            WriteInt16(replyRelBindingPos, 99);
                            return;
                        }

                        //获取子码绑定的类型
                        var codeTypePosition = DecodeValue.GetPositionByActionKey(position, SubcodeBindingName.CodeTypeAction);
                        if (codeTypePosition == null) {
                            WriteLogUI($"子码编号类型，未配置绑定的子码编号类型ActionKey字段");
                            WriteInt16(replyRelBindingPos, -1);
                            return;
                        }
                        //获取子码类型值
                        var codeTypeValue = DecodeValue.GetLinkDecodeObject(codeTypePosition).Value.ToInt();
                        if (codeTypeValue <= 0) {
                            WriteLogUI($"子码类型值必须大于0");
                            WriteInt16(replyRelBindingPos, 98);
                            return;
                        }

                        eBarCodeRelType eCodeTypeValue = 0;  // 默认值
                        if (Enum.TryParse(codeTypeValue.ToString(), out eCodeTypeValue) && Enum.IsDefined(typeof(eBarCodeRelType), eCodeTypeValue)) {
                            // 成功转换 Do Nothing
                            Debug.WriteLine(codeTypeValue);
                        } else {
                            // 处理未找到匹配的情况
                            WriteLogUI("没有找到匹配子码类型的枚举值");
                            WriteInt16(replyRelBindingPos, -1);
                            return;
                        }

                        //验证是否重复绑定
                        var barRelRec = conn.Select<CksBarcodeRelationshipRecord>().Where(o => o.PlcID == position.PlcId && o.ReadDB == position.BlockDb  && o.PrimaryCode == mainCodeBindingValue).ToList();
                        if (barRelRec != null && barRelRec.Any(o => !o.IsDeleted)) {
                            var rec = barRelRec.Where(o => !o.IsDeleted).FirstOrDefault();
                            WriteLogUI($"当前主产品码已存在绑定关系，绑定记录ID：{rec.Id}，主码：{mainCodeBindingValue}，已绑定子码：{rec.SubcodeCode}");
                            WriteInt16(replyRelBindingPos, 11);
                            return;
                        }
                        barRelRec = conn.Select<CksBarcodeRelationshipRecord>().Where(o => o.PlcID == position.PlcId && o.ReadDB == position.BlockDb  && o.SubcodeCode == subCodeValue).ToList();
                        if (barRelRec != null && barRelRec.Any(o => !o.IsDeleted)) {
                            var rec = barRelRec.Where(o => !o.IsDeleted).FirstOrDefault();
                            WriteLogUI($"当前子码已存在绑定关系，绑定记录ID：{rec.Id}，子码：{subCodeValue}，已绑定主产品码：{rec.PrimaryCode}");
                            WriteInt16(replyRelBindingPos, 11);
                            return;
                        }

                        CksBarcodeRelationshipRecord cksBarcodeRelationshipRecord = new CksBarcodeRelationshipRecord {
                            PrimaryCode = mainCodeBindingValue,
                            SubcodeCode = subCodeValue,
                            PlcID = position.PlcId,
                            Type = eCodeTypeValue,
                            CreatedTime = DateTime.Now,
                            ReadDB = position.BlockDb, //设置读取DB块
                        };
                        //插入新条码关系记录
                        var diff = conn.Insert(cksBarcodeRelationshipRecord).ExecuteAffrows();
                        if (diff <= 0) {
                            WriteInt16(replyRelBindingPos, 2);
                        }
                        WriteInt16(replyRelBindingPos, 1);
                        WriteLogUI($"子码关系绑定记录，主码：{mainCodeBindingValue}，子码：{subCodeValue}，保存子码绑定关系成功");
                    }

                } else if (result == 2) {//批次码绑定

                    //获取子码字段位置
                    var subCodePosition = DecodeValue.GetPositionByActionKey(position, SubcodeBindingName.SubCodeBindingActionKey);
                    if (subCodePosition == null) {
                        WriteLogUI($"子码，未配置子码绑定的ActionKey子码字段");
                        WriteInt16(replyRelBindingPos, -1);
                        return;
                    }

                    //获取子码值
                    var subCodeValue = DecodeValue.GetLinkDecodeObject(subCodePosition).CharString.TrimEnd();
                    //如果子码值为空，则不进行处理
                    if (string.IsNullOrEmpty(subCodeValue)) {
                        WriteLogUI("子码绑定值为空");
                        WriteInt16(replyRelBindingPos, 99);
                        return;
                    }

                    //获取子码绑定的类型
                    var codeTypePosition = DecodeValue.GetPositionByActionKey(position, SubcodeBindingName.CodeTypeAction);
                    if (codeTypePosition == null) {
                        WriteLogUI($"子码编号类型，未配置绑定的子码编号类型ActionKey字段");
                        WriteInt16(replyRelBindingPos, -1);
                        return;
                    }

                    //获取子码类型值
                    var codeTypeValue = DecodeValue.GetLinkDecodeObject(codeTypePosition).Value.ToInt();
                    if (codeTypeValue <= 0) {
                        WriteLogUI($"子码类型值必须大于0");
                        WriteInt16(replyRelBindingPos, 98);
                        return;
                    }

                    var affrowCut = 0;
                    //查询子码类型在当前站点是否存在，如果存在则作废，新增批次记录
                    var curUseBatchCode = conn.Select<CksBatchCodeData>().Where(o => o.PlcId == position.PlcId && o.DbBlock == position.BlockDb && o.Type == codeTypeValue && !o.Nullity).ToList().LastOrDefault();
                    if (curUseBatchCode != null) {
                        curUseBatchCode.Nullity = true;
                        curUseBatchCode.ModifyTime = DateTime.Now;
                        var affrow1 = conn.Update<CksBatchCodeData>().SetSource(curUseBatchCode).UpdateColumns(o => new { o.Nullity, o.ModifyTime }).Where(o => o.Id == curUseBatchCode.Id).ExecuteAffrows();
                        affrowCut = affrowCut + affrow1;
                    }

                    var batchCodeData = new CksBatchCodeData {
                        PlcId = position.PlcId,
                        DbBlock = position.BlockDb,
                        BatchCode = subCodeValue,
                        Type = codeTypeValue,
                        Nullity = false,
                        CreateTime = DateTime.Now
                    };
                    var affrow2 = conn.Insert<CksBatchCodeData>(batchCodeData).ExecuteAffrows();
                    affrowCut = affrowCut + affrow2;

                    if (affrowCut < 1) {
                        WriteInt16(replyRelBindingPos, (short)2);
                        WriteLogUI($"批次码绑定记录，批次码：{subCodeValue}，保存批次码失败");
                        return;
                    }

                    WriteInt16(replyRelBindingPos, (short)1);
                    WriteLogUI($"批次码绑定记录，批次码：{subCodeValue}，保存批次码成功");

                } else {

                    WriteInt16(replyRelBindingPos, 0);
                    WriteLogUI($"子码绑定重置");

                }
            }

        }

    }

    public static class SubcodeBindingName {

        /// <summary>
        /// 子码绑定订阅点的ActionKey
        /// </summary>
        public const string SubscribeBindingActionKey = "SubcodeBindingSubscribe";

        /// <summary>
        /// 主码ActionKey
        /// </summary>
        public const string PrimaryCodeBindingActionKey = "BindingPrimaryCode";

        /// <summary>
        /// 子码ActionKey
        /// </summary>
        public const string SubCodeBindingActionKey = "BindingSubCode";

        /// <summary>
        /// 托盘码ActionKey
        /// </summary>
        public const string PalletCodeBindingActionKey = "BindingPalletCode";

        /// <summary>
        /// 子码绑定的代码类型
        /// </summary>
        public const string CodeTypeAction = "BindingCodeType";

    }

}
